package com.shhm.common.utils;

import com.alibaba.fastjson2.JSON;
import com.shhm.common.entity.admin.SysRoleOperatePerms;
import com.shhm.common.entity.system.SysPassAuth;
import com.shhm.common.entity.system.SysRedisCache;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;

import java.util.*;

/**
 * @author JackZ
 * @version 1.0
 * @description: 验证码处理
 * @date 2025/7/15 下午3:17
 */
public class RedisUtil {
    /**
     * 登录key
     */
    public static final String REDIS_LOGIN_KEY="system:sys_captcha:login";

    public static final String REDIS_REGISTER_KEY="system:sys_captcha:register";
    /**
     * 验证码最多错误次数
     */
    public static final String REDIS_LOGIN_CAPTCHA_RETRY="5";
    /**
     * 角色操作权限字符key
     */
    public static final String REDIS_OPERATE_PERMS_KEY="system:sys_role_operate_perms:";
    /**
     * 用户登录信息key
     */
    public static final String REDIS_USER_ONLINE_KEY="user:online:info:u";
    /**
     * 用户登录令牌缓存key
     */
    public static final String REDIS_TOKEN_ONLINE_KEY="user:online:token:u";
    /**
     * 用户登录令牌黑名单key
     */
    public static final String REDIS_BLACK_TOKEN_KEY="user:black:token:u";
    /**
     * 过滤器白名单 key
     */
    public static final String REDIS_AUTH_PASS_KEY="system:sys_pass_auth:";

    /**
     * 刷新角色操作权限缓存
     */
    public static void flushSysRoleOperatePerms(List<SysRoleOperatePerms> list,RedisTemplate<String, String> redisTemplate){
        removePrefixData(redisTemplate,REDIS_OPERATE_PERMS_KEY);
        Map<String,List<SysRoleOperatePerms>> srop = new HashMap<>();
        list.forEach(l->{
            if (srop.containsKey(l.getRoleKey())) srop.get(l.getRoleKey()).add(l);
            else {
                ArrayList<SysRoleOperatePerms> sysRoleOperatePerms = new ArrayList<>();
                sysRoleOperatePerms.add(l);
                srop.put(l.getRoleKey(), sysRoleOperatePerms);
            }
        });
        srop.forEach((k,v)->redisTemplate.opsForValue().set(REDIS_OPERATE_PERMS_KEY+k,JSON.toJSONString(v)));
    }

    public static void flushSysAuthWhite(RedisTemplate<String, String> redisTemplate, List<SysPassAuth> whiteList){
        removePrefixData(redisTemplate,REDIS_AUTH_PASS_KEY);
        Map<String,List<SysPassAuth>> palist = new HashMap<>();
        whiteList.forEach(l->{
            if (palist.containsKey(l.getAuthKey())) palist.get(l.getAuthKey()).add(l);
            else {
                ArrayList<SysPassAuth> passAuthArrayList = new ArrayList<>();
                passAuthArrayList.add(l);
                palist.put(l.getAuthKey(), passAuthArrayList);
            }
        });
        palist.forEach((k,v)->redisTemplate.opsForValue().set(REDIS_AUTH_PASS_KEY+k,JSON.toJSONString(v)));
    }

    /**
     * 批量删除键前缀为prefix的数据
     */
    public static Integer removePrefixData(RedisTemplate<String, String> redisTemplate,String prefix){
        ScanOptions build = ScanOptions.scanOptions().match(prefix+"*").count(100).build();
        Cursor<String> scan = redisTemplate.scan(build);
        Integer count=0;
        while (scan.hasNext()){
            String key = scan.next();
            if (redisTemplate.delete(key)) {
                count++;
            }
        }
        try {
            scan.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 批量获取键前缀为prefix的数据
     * @param redisTemplate
     * @return List
     */
    public static <T> List<T> getPrefixData(
            RedisTemplate<String, String> redisTemplate,
            SysRedisCache sysRedisCache,
            Class<T> type
    ){
        ScanOptions build = ScanOptions.scanOptions()
                .match(sysRedisCache.getCacheKey())
                .count(sysRedisCache.getLimit())
                .build();
        Cursor<String> scan = redisTemplate.scan(build);
        List<T> list = new ArrayList<>();
        while (scan.hasNext()){
            String key = scan.next();
            String value = redisTemplate.opsForValue().get(key);
            List list1 = JSON.parseObject(value, List.class);
            list.addAll(list1);
        }
        return list;
    }

    /**
     * 根据rolekey和requestUri获取权限字符
     * @param redisTemplate
     * @param roleKey
     * @param requestUri
     * @return 权限字符
     */
    public static String getRoleOperatePerms(RedisTemplate<String, String> redisTemplate,String roleKey,String requestUri){
        String opeStr="n";
        String s = redisTemplate.opsForValue().get(REDIS_OPERATE_PERMS_KEY+roleKey);
        List<SysRoleOperatePerms> list = JSON.parseArray(s, SysRoleOperatePerms.class);
        if (Objects.isNull(list)||list.isEmpty()) return opeStr;
        for (SysRoleOperatePerms item : list) {
            if (item.getRoleKey().equals(roleKey)&&item.getRequestUri().equals(requestUri)) {
                opeStr=item.getOperateStr();
                break;
            }
        }
        return opeStr;
    }
}
